package values

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"time"
)

// ToInt 转换目标为 Int, 如果转换失败, 则返回0
func ToInt(v any) int {
	if v == nil {
		return 0
	}
	to, _ := ToIntE(v)
	return to
}

// ToIntD 转换目标为 Int, 如果目标为Nil或转换失败, 则返回defaultVal指定的默认值
func ToIntD(v any, defaultVal int) int {
	if v == nil {
		return defaultVal
	}
	if to, err := ToIntE(v); err == nil {
		return to
	}
	return defaultVal
}

// ToIntE  转换目标为 Int, 如果转换失败, 则返回0和错误信息
func ToIntE(v any) (int, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToIntE: unable to nil to int")
	}
	switch vs := v.(type) {
	case int:
		return vs, nil
	case int64:
		if vs <= math.MaxInt && vs >= math.MinInt {
			return int(vs), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of type int64 to int, value out of range", v)
	case int32:
		return int(vs), nil
	case int16:
		return int(vs), nil
	case int8:
		return int(vs), nil
	case uint:
		if vs <= math.MaxInt {
			return int(vs), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of type uint to int, value out of range", v)
	case uint64:
		if vs <= math.MaxInt {
			return int(vs), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of type uint64 to int, value out of range", v)
	case uint32:
		return int(vs), nil
	case uint16:
		return int(vs), nil
	case uint8:
		return int(vs), nil
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToIntE: unable to %v of type float64 to int, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxInt / MinInt 区间
		if vs > float64(math.MaxInt) || vs < float64(math.MinInt) {
			return 0, fmt.Errorf("ToIntE: unable to %v of type float64 to int, value out of range", v)
		}
		return int(vs), nil

	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToIntE: unable to %v of type float32 to int, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxInt / MinInt 区间
		if vs64 > float64(math.MaxInt) || vs64 < float64(math.MinInt) {
			return 0, fmt.Errorf("ToIntE: unable to %v of type float32 to int, value out of range", v)
		}
		return int(vs64), nil
	case string:
		return StringToIntE(vs)
	case json.Number:
		return StringToIntE(string(vs))
	case time.Weekday:
		return int(vs), nil
	case time.Month:
		return int(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerInt:
		return vs.Int(), nil
	case providerInt64:
		vss := vs.Int64()
		if vss >= math.MinInt && vss <= math.MaxInt {
			return int(vss), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of interface Int64() to int, value out of range", v)
	case providerInt32:
		return int(vs.Int32()), nil
	case providerInt16:
		return int(vs.Int16()), nil
	case providerInt8:
		return int(vs.Int8()), nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxInt {
			return int(vs.Uint()), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of interface Uint() to int64, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxInt {
			return int(vss), nil
		}
		return 0, fmt.Errorf("ToIntE: unable to %v of interface Uint64() to int64, value out of range", v)
	case providerUint32:
		return int(vs.Uint32()), nil
	case providerUint16:
		return int(vs.Uint16()), nil
	case providerUint8:
		return int(vs.Uint8()), nil
	case providerFloat:
		vss, err := ToIntE(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToIntE: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToIntE(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToIntE: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToIntE(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToIntE: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToIntE: unable to %#v of type %T to int", v, v)
	}
}

// ToInt8 转换目标为 Int8, 如果转换失败, 则返回0
func ToInt8(v any) int8 {
	if v == nil {
		return 0
	}
	to, _ := ToInt8E(v)
	return to
}

// ToInt8D 转换目标为 Int8, 如果转换失败, 则返回defaultVal指定的默认值
func ToInt8D(v any, defaultVal int8) int8 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToInt8E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToInt8E  转换目标为 Int8, 如果转换失败, 则返回0和错误信息
func ToInt8E(v any) (int8, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToInt8E: unable to nil to int8")
	}
	switch vs := v.(type) {
	case int:
		if vs <= math.MaxInt8 && vs >= math.MinInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type int to int8, value out of range", v)
	case int64:
		if vs <= math.MaxInt8 && vs >= math.MinInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type int64 to int8, value out of range", v)
	case int32:
		if vs <= math.MaxInt8 && vs >= math.MinInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type int32 to int8, value out of range", v)
	case int16:
		if vs <= math.MaxInt8 && vs >= math.MinInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type int16 to int8, value out of range", v)
	case int8:
		return vs, nil
	case uint:
		if vs <= math.MaxInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type uint to int8, value out of range", v)
	case uint64:
		if vs <= math.MaxInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type uint64 to int8, value out of range", v)
	case uint32:
		if vs <= math.MaxInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type uint32 to int8, value out of range", v)
	case uint16:
		if vs <= math.MaxInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type uint16 to int8, value out of range", v)
	case uint8:
		if vs <= math.MaxInt8 {
			return int8(vs), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of type uint8 to int8, value out of range", v)
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToInt8E: unable to %v of type float64 to int8, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxInt8 / MinInt8 区间
		if vs > float64(math.MaxInt8) || vs < float64(math.MinInt8) {
			return 0, fmt.Errorf("ToInt8E: unable to %v of type float64 to int8, value out of range", v)
		}
		return int8(vs), nil

	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToInt8E: unable to %v of type float32 to int8, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxInt / MinInt 区间
		if vs64 > float64(math.MaxInt8) || vs64 < float64(math.MinInt8) {
			return 0, fmt.Errorf("ToInt8E: unable to %v of type float32 to int8, value out of range", v)
		}
		return int8(vs64), nil
	case string:
		return StringToInt8E(vs)
	case json.Number:
		return StringToInt8E(string(vs))
	case time.Weekday:
		return int8(vs), nil
	case time.Month:
		return int8(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerInt:
		vss := vs.Int()
		if vss >= math.MinInt8 && vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Int() to int8, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= math.MinInt8 && vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Int64() to int8, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= math.MinInt8 && vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Int32() to int8, value out of range", v)
	case providerInt16:
		vss := vs.Int16()
		if vss >= math.MinInt8 && vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Int16() to int8, value out of range", v)
	case providerInt8:
		return vs.Int8(), nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Uint() to int8, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Uint64() to int8, value out of range", v)
	case providerUint32:
		vss := vs.Uint32()
		if vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Uint32() to int8, value out of range", v)
	case providerUint16:
		vss := vs.Uint16()
		if vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Uint16() to int8, value out of range", v)
	case providerUint8:
		vss := vs.Uint8()
		if vss <= math.MaxInt8 {
			return int8(vss), nil
		}
		return 0, fmt.Errorf("ToInt8E: unable to %v of interface Uint8() to int8, value out of range", v)
	case providerFloat:
		vss, err := ToInt8E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToInt8E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToInt8E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToInt8E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToInt8E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToInt8E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToInt8E: unable to %#v of type %T to int8", v, v)
	}
}

// ToInt16 转换目标为 Int16, 如果转换失败, 则返回0
func ToInt16(v any) int16 {
	if v == nil {
		return 0
	}
	to, _ := ToInt16E(v)
	return to
}

// ToInt16D 转换目标为 Int16, 如果转换失败, 则返回defaultVal指定的默认值
func ToInt16D(v any, defaultVal int16) int16 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToInt16E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToInt16E  转换目标为 Int16, 如果转换失败, 则返回0和错误信息
func ToInt16E(v any) (int16, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToInt16E: unable to nil to int16")
	}
	switch vs := v.(type) {
	case int:
		if vs <= math.MaxInt16 && vs >= math.MinInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type int to int16, value out of range", v)
	case int64:
		if vs <= math.MaxInt16 && vs >= math.MinInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type int64 to int16, value out of range", v)
	case int32:
		if vs <= math.MaxInt16 && vs >= math.MinInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type int32 to int16, value out of range", v)
	case int16:
		return vs, nil
	case int8:
		return int16(vs), nil
	case uint:
		if vs <= math.MaxInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type uint to int16, value out of range", v)
	case uint64:
		if vs <= math.MaxInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type uint64 to int16, value out of range", v)
	case uint32:
		if vs <= math.MaxInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type uint32 to int16, value out of range", v)
	case uint16:
		if vs <= math.MaxInt16 {
			return int16(vs), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of type uint16 to int16, value out of range", v)
	case uint8:
		return int16(vs), nil
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToInt16E: unable to %v of type float64 to int16, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxInt16 / MinInt16 区间
		if vs > float64(math.MaxInt16) || vs < float64(math.MinInt16) {
			return 0, fmt.Errorf("ToInt16E: unable to %v of type float64 to int16, value out of range", v)
		}
		return int16(vs), nil

	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToInt16E: unable to %v of type float32 to int16, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxInt / MinInt 区间
		if vs64 > float64(math.MaxInt16) || vs64 < float64(math.MinInt16) {
			return 0, fmt.Errorf("ToInt16E: unable to %v of type float32 to int16, value out of range", v)
		}
		return int16(vs64), nil
	case string:
		return StringToInt16E(vs)
	case json.Number:
		return StringToInt16E(string(vs))
	case time.Weekday:
		return int16(vs), nil
	case time.Month:
		return int16(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerInt:
		vss := vs.Int()
		if vss >= math.MinInt16 && vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Int() to int16, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= math.MinInt16 && vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Int64() to int16, value out of range", v)
	case providerInt32:
		vss := vs.Int32()
		if vss >= math.MinInt16 && vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Int32() to int16, value out of range", v)
	case providerInt16:
		return vs.Int16(), nil
	case providerInt8:
		return int16(vs.Int8()), nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Uint() to int16, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Uint64() to int16, value out of range", v)
	case providerUint32:
		vss := vs.Uint32()
		if vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Uint32() to int16, value out of range", v)
	case providerUint16:
		vss := vs.Uint16()
		if vss <= math.MaxInt16 {
			return int16(vss), nil
		}
		return 0, fmt.Errorf("ToInt16E: unable to %v of interface Uint16() to int16, value out of range", v)
	case providerUint8:
		return int16(vs.Uint8()), nil
	case providerFloat:
		vss, err := ToInt16E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToInt16E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToInt16E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToInt16E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToInt16E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToInt16E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToInt16E: unable to %#v of type %T to int16", v, v)
	}
}

// ToInt32 转换目标为 Int32, 如果转换失败, 则返回0
func ToInt32(v any) int32 {
	if v == nil {
		return 0
	}
	to, _ := ToInt32E(v)
	return to
}

// ToInt32D 转换目标为 Int32, 如果转换失败, 则返回defaultVal指定的默认值
func ToInt32D(v any, defaultVal int32) int32 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToInt32E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToInt32E  转换目标为 Int32, 如果转换失败, 则返回0和错误信息
func ToInt32E(v any) (int32, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToInt32E: unable to nil to int32")
	}
	switch vs := v.(type) {
	case int:
		if vs <= math.MaxInt32 && vs >= math.MinInt32 {
			return int32(vs), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of type int to int32, value out of range", v)
	case int64:
		if vs <= math.MaxInt32 && vs >= math.MinInt32 {
			return int32(vs), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of type int64 to int32, value out of range", v)
	case int32:
		return vs, nil
	case int16:
		return int32(vs), nil
	case int8:
		return int32(vs), nil
	case uint:
		if vs <= math.MaxInt32 {
			return int32(vs), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of type uint to int32, value out of range", v)
	case uint64:
		if vs <= math.MaxInt32 {
			return int32(vs), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of type uint64 to int32, value out of range", v)
	case uint32:
		if vs <= math.MaxInt32 {
			return int32(vs), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of type uint32 to int32, value out of range", v)
	case uint16:
		return int32(vs), nil
	case uint8:
		return int32(vs), nil
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToInt32E: unable to %v of type float64 to int32, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxInt32 / MinInt32 区间
		if vs > float64(math.MaxInt32) || vs < float64(math.MinInt32) {
			return 0, fmt.Errorf("ToInt32E: unable to %v of type float64 to int32, value out of range", v)
		}
		return int32(vs), nil

	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToInt32E: unable to %v of type float32 to int32, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxInt / MinInt 区间
		if vs64 > float64(math.MaxInt32) || vs64 < float64(math.MinInt32) {
			return 0, fmt.Errorf("ToInt32E: unable to %v of type float32 to int32, value out of range", v)
		}
		return int32(vs64), nil
	case string:
		return StringToInt32E(vs)
	case json.Number:
		return StringToInt32E(string(vs))
	case time.Weekday:
		return int32(vs), nil
	case time.Month:
		return int32(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerInt:
		vss := vs.Int()
		if vss >= math.MinInt32 && vss <= math.MaxInt32 {
			return int32(vss), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of interface Int() to int32, value out of range", v)
	case providerInt64:
		vss := vs.Int64()
		if vss >= math.MinInt32 && vss <= math.MaxInt32 {
			return int32(vss), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of interface Int64() to int32, value out of range", v)
	case providerInt32:
		return vs.Int32(), nil
	case providerInt16:
		return int32(vs.Int16()), nil
	case providerInt8:
		return int32(vs.Int8()), nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxInt32 {
			return int32(vss), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of interface Uint() to int32, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxInt32 {
			return int32(vss), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of interface Uint64() to int32, value out of range", v)
	case providerUint32:
		vss := vs.Uint32()
		if vss <= math.MaxInt32 {
			return int32(vss), nil
		}
		return 0, fmt.Errorf("ToInt32E: unable to %v of interface Uint32() to int32, value out of range", v)
	case providerUint16:
		return int32(vs.Uint16()), nil
	case providerUint8:
		return int32(vs.Uint8()), nil
	case providerFloat:
		vss, err := ToInt32E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToInt32E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToInt32E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToInt32E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToInt32E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToInt32E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToInt32E: unable to %#v of type %T to int32", v, v)
	}
}

// ToInt64 转换目标为 Int64, 如果转换失败, 则返回0
func ToInt64(v any) int64 {
	if v == nil {
		return 0
	}
	to, _ := ToInt64E(v)
	return to
}

// ToInt64D 转换目标为 Int64, 如果转换失败, 则返回defaultVal指定的默认值
func ToInt64D(v any, defaultVal int64) int64 {
	if v == nil {
		return defaultVal
	}
	if to, err := ToInt64E(v); err == nil {
		return to
	}
	return defaultVal
}

// ToInt64E  转换目标为 Int64, 如果转换失败, 则返回0和错误信息
func ToInt64E(v any) (int64, error) {
	v = UnderefVal(v)
	if v == nil {
		return 0, errors.New("ToInt64E: unable to nil to int64")
	}
	switch vs := v.(type) {
	case int:
		return int64(vs), nil
	case int64:
		return vs, nil
	case int32:
		return int64(vs), nil
	case int16:
		return int64(vs), nil
	case int8:
		return int64(vs), nil
	case uint:
		if vs <= math.MaxInt64 {
			return int64(vs), nil
		}
		return 0, fmt.Errorf("ToInt64E: unable to %v of type uint to int64, value out of range", v)
	case uint64:
		if vs <= math.MaxInt64 {
			return int64(vs), nil
		}
		return 0, fmt.Errorf("ToInt64E: unable to %v of type uint64 to int64, value out of range", v)
	case uint32:
		return int64(vs), nil
	case uint16:
		return int64(vs), nil
	case uint8:
		return int64(vs), nil
	case float64:
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs) || math.IsInf(vs, 0) {
			return 0, fmt.Errorf("ToInt64E: unable to %v of type float64 to int64, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs, _ = math.Modf(vs)
		// 整数是否在 MaxInt64 / MinInt64 区间
		if vs > float64(math.MaxInt64) || vs < float64(math.MinInt64) {
			return 0, fmt.Errorf("ToInt64E: unable to %v of type float64 to int64, value out of range", v)
		}
		return int64(vs), nil

	case float32:
		vs64 := float64(vs)
		// 是否特殊浮点数（如NaN、正无穷、负无穷）则无法将其转换为整数
		if math.IsNaN(vs64) || math.IsInf(vs64, 0) {
			return 0, fmt.Errorf("ToInt64E: unable to %v of type float32 to int64, value out of range", v)
		}
		// 向下取整, 分离后取得整数部分
		vs64, _ = math.Modf(vs64)
		// 整数是否在 MaxInt / MinInt 区间
		if vs64 > float64(math.MaxInt64) || vs64 < float64(math.MinInt64) {
			return 0, fmt.Errorf("ToInt64E: unable to %v of type float32 to int64, value out of range", v)
		}
		return int64(vs64), nil
	case string:
		return StringToInt64E(vs)
	case json.Number:
		return StringToInt64E(string(vs))
	case time.Weekday:
		return int64(vs), nil
	case time.Month:
		return int64(vs), nil
	case bool:
		if vs {
			return 1, nil
		}
		return 0, nil
	case providerInt:
		return int64(vs.Int()), nil
	case providerInt64:
		return vs.Int64(), nil
	case providerInt32:
		return int64(vs.Int32()), nil
	case providerInt16:
		return int64(vs.Int16()), nil
	case providerInt8:
		return int64(vs.Int8()), nil
	case providerUint:
		vss := vs.Uint()
		if vss <= math.MaxInt64 {
			return int64(vss), nil
		}
		return 0, fmt.Errorf("ToInt64E: unable to %v of interface Uint() to int64, value out of range", v)
	case providerUint64:
		vss := vs.Uint64()
		if vss <= math.MaxInt64 {
			return int64(vss), nil
		}
		return 0, fmt.Errorf("ToInt64E: unable to %v of interface Uint64() to int64, value out of range", v)
	case providerUint32:
		return int64(vs.Uint32()), nil
	case providerUint16:
		return int64(vs.Uint16()), nil
	case providerUint8:
		return int64(vs.Uint8()), nil
	case providerFloat:
		vss, err := ToInt64E(vs.Float())
		if err != nil {
			return 0, fmt.Errorf("ToInt64E: unable to %v of interface Float(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat64:
		vss, err := ToInt64E(vs.Float64())
		if err != nil {
			return 0, fmt.Errorf("ToInt64E: unable to %v of interface Float64(), %s", v, err.Error())
		}
		return vss, nil
	case providerFloat32:
		vss, err := ToInt64E(vs.Float32())
		if err != nil {
			return 0, fmt.Errorf("ToInt64E: unable to %v of interface Float32(), %s", v, err.Error())
		}
		return vss, nil
	default:
		return 0, fmt.Errorf("ToInt64E: unable to %#v of type %T to int64", v, v)
	}
}
